/*
 * One example for NOI CSP-J Lesson 6:
 * <https://courses.fmsoft.cn/plzs/noijunior-search-algorithms.html>
 *
 * Author: Vincent Wei
 *  - <https://github.com/VincentWei>
 *  - <https://gitee.com/vincentwei7>
 *
 * Copyright (C) 2025 FMSoft <https://www.fmsoft.cn>.
 * License: GPLv3
 */

#include <iostream>       // std::cout
#include <string>         // std::string

int main ()
{
    std::string haystack("There  \t are   two \t needles in this\fhaystack with\nneedles.");
    std::string needle("needle");

    // 和针对容器的迭代子不同，字符串的查找接口返回字符的位置（索引值）
    std::size_t found = haystack.find(needle);

    // 注意 std::string::npos 是一个预定义常量，表示不存在的位置（-1）
    if (found != std::string::npos)
        std::cout << "first 'needle' found at: " << found << '\n';

    // 指定查找的起始位置以及要匹配的长度
    found = haystack.find("needles are small", found + needle.length(),
            needle.length());
    if (found != std::string::npos)
        std::cout << "second 'needle' found at: " << found << '\n';

    found= haystack.find("haystack");
    if (found != std::string::npos)
        std::cout << "'haystack' also found at: " << found << '\n';

    // 指定最后一次出现的位置
    found = haystack.rfind(needle);
    if (found != std::string::npos)
        std::cout << "The last occurrence of 'needle' found at: " << found <<
            std::endl;

    // 替代第一次出现的 `needle` 为 `preposition`
    haystack.replace(haystack.find(needle), needle.length(), "preposition");
    std::cout << haystack << std::endl;

    // 查找匹配 ` \t\n\r\f.,;'"` 中任意一个字符的字符所在位置
    // 从而使用空白字符、标点符号等找出字符串中的英文单词或数字。
    std::string seperators(" \t\n\r\f.,;'\"");
    while (true) {
        std::size_t token_start = haystack.find_first_not_of(seperators);
        if (token_start == std::string::npos) {
            break;
        }

        std::size_t token_end = haystack.find_first_of(seperators, token_start);
        if (token_end == std::string::npos) {
            token_end = haystack.length();
        }

        if (token_end > token_start) {
            std::string token = haystack.substr(token_start,
                    token_end - token_start);
            std::cout << "Got a token: `" << token << "`\n";
        }

        // 往后继续
        haystack = haystack.substr(token_end);
    }

    return 0;
}

